#pragma once
#include <string>
#include <list>
using namespace std;

class UserInfo {
public:
	enum user_type {
		USER_TYPE_CALLER, USER_TYPE_CALLEE
	};
	UserInfo(const string &name, user_type usertype, const string &callId) :
		m_name(name), m_type(usertype), m_callId(callId) {
	}
	string GetName() const {
		return m_name;
	}
	string GetCallId() const {
		return m_callId;
	}
	user_type GetType() const {
		return m_type;
	}
protected:
	friend bool operator <(const UserInfo & userinfo1,
			const UserInfo & userinfo2);
	string m_name;
	user_type m_type;
	string m_callId;
};

// TODO add calling time control
class Caller: public UserInfo {
public:
	Caller(const string &name, const string &callId, const string &password, int callerTime) :
		UserInfo(name, USER_TYPE_CALLER, callId)
	, m_password(password)
	, m_totalCallTime(callerTime*1000)
	, m_availableCallTime(0)
	, m_sessionCalledTime(0)
	{
	}
	string GetPassword() const {
		return m_password;
	}
	time_t totalCallTime() const {
		return m_totalCallTime;
	}
	void setTotalCallTime(time_t time) {
		m_totalCallTime = time;
	}
	time_t availableCallTime() const {
		return m_availableCallTime;
	}
	void setAvailableCallTime(time_t time) {
		m_availableCallTime = time;
	}
	time_t sessionCalledTime() const {
		return m_sessionCalledTime;
	}
	void setSessionCalledTime(time_t time) {
		m_sessionCalledTime = time;
	}
private:
	string m_password;
	// total called time sum of all sessions
	time_t m_totalCallTime;
	// total available call time, if totalCallTime reach this value, it should not call again.
	time_t m_availableCallTime;
	// if in calling, this variable records the time of this calling called.
	time_t m_sessionCalledTime;
};
class Callee: public UserInfo {
public:
	Callee(const string &name, const string &callId, const string &password) :
		UserInfo(name, USER_TYPE_CALLEE, callId) {
	}
};

typedef list<Caller> CallerList;
typedef list<Callee> CalleeList;


class CallingData {
public:
	enum State {
		STATE__LOGINED,
		STATE__ONLINE,
		STATE__FAILED,
		STATE__TIMEOUT,
		STATE__REFUSED,
		STATE__BUSY,
		STATE__MISSED,
		STATE__FINISHED
	};
	CallingData(void);
	~CallingData(void);

	Caller* caller() {
		return m_caller;
	}
	void setCaller(Caller* value) {
		m_caller = value;
	}

	Callee* callee() {
		return m_callee;
	}
	void setCallee(Callee* value) {
		m_callee = value;
	}

	time_t startTime() {
		return m_startTime;
	}
	void setStartTime(time_t value) {
		m_startTime = value;
	}

	time_t endTime() {
		return m_endTime;
	}
	void setEndTime(time_t value) {
		m_endTime = value;
	}

	State state() {
		return m_state;
	}
	void setState(State value) {
		m_state = value;
	}

private:
	Caller* m_caller;
	Callee* m_callee;
	time_t m_startTime;
	time_t m_endTime;
	State m_state;
};

bool operator <(const UserInfo & userinfo1, const UserInfo & userinfo2);
